const Koa = require('koa')
const Router = require('koa-router');
const path = require('path')
const jsonp = require('koa-jsonp')
const koaBody = require('koa-body')
const cors = require('koa2-cors')
const fs = require('fs-extra')
const static = require('koa-static')
const os = require('os')

/* 当前上传目录（路劲） */
let FilePath = path.join(os.homedir(), '.file-chunk', 'Files')

/* 碎片文件（临时） */
const hashFile = path.join(os.homedir(), '.file-chunk', 'hashFile')

fs.ensureDirSync(FilePath)
fs.ensureDirSync(hashFile)

const app = new Koa()

const router = new Router();

/* 跨域 */
app.use(cors())


app.use(jsonp())

/* 静态资源 */
app.use(static(__dirname + '/static'))

app.use(koaBody({
    multipart: true,
    formidable: {
        maxFileSize: 5000 * 1024 * 1024    // 设置上传文件大小最大限制，默认2M
    }
}));




/* 确保hashFile目录存在，不存在则创建 */
fs.ensureDirSync(hashFile)

/* 文件移动 */
function CloudFileMove(tempPath, filePath) {
    return new Promise((resolve) => {
        fs.move(tempPath, filePath, function (err) {
            let info = { code: err ? 500 : 200 }
            err && (info.err = err)
            resolve(info)
        })
    })
}


// 大文件切片上传
router.post('/transmission/chunk-upload', async (ctx) => {
    /* 文件对象 */
    let { file } = ctx.request.files
    /* 文件id，文件下标 */
    let { fileId, index } = ctx.request.body
    /* 根据文件ID创建临时切片文件 */
    console.log(JSON.stringify(fileId));
    fs.ensureDirSync(`${hashFile}/${fileId}`)
    // 文件移动
    const result = await CloudFileMove(file.path, `${hashFile}/${fileId}/${index}`)
    /* 返回前端状态码，以及文件编号 */
    ctx.body = { ...result, index }
})

/* 读取文件，检测服务端是否有上次未完成的上传任务 */
router.post('/transmission/chunk-read', async (ctx) => {
    let { fileId } = ctx.request.body
    const hashs = fs.readdirSync(hashFile)

    const dir = hashs[hashs.indexOf(fileId)]

    let sliceChunks = !dir ? [] : fs.readdirSync(`${hashFile}/${dir}`).sort((a, b) => a - b)

    ctx.body = { code: 200, sliceChunks }
})
// 切片合并
router.post('/transmission/chunk-all', async (ctx) => {
    let { fileId, fileName } = ctx.request.body

    let body = { code: 200 }



    /* 确保FilePath目录存在，不存在则创建 */
    fs.ensureDirSync(FilePath)

    /* 切片目录（路劲） */
    let hashPath = `${hashFile}/${fileId}`

    /* 切片集合（排序） */
    let chunks = fs.readdirSync(hashPath).sort((a, b) => a - b)

    /* 创建空文件 */
    fs.writeFileSync(`${FilePath}/${fileName}`, '')

    /* 检测文件是否存在 */
    const isThere = fs.existsSync(`${FilePath}/${fileName}`)

    /* 文件不存在，退出接口逻辑 */
    if (!isThere) {
        ctx.body = { code: 404 }
    }

    // 提取分片数据，进行资源整合
    for (let i = 0; i < chunks.length; i++) {
        let item = chunks[i]
        try {
            let temp = fs.readFileSync(`${hashPath}/${item}`)
            fs.appendFileSync(`${FilePath}/${fileName}`, temp)
        } catch (error) {
            body.code = 500
            body.errInfo = error
            break
        }
    }

    /* 删除分片数据 */

    if (body.code === 200) {
        fs.removeSync(hashPath)
    }

    ctx.body = body

})

app.use(router.routes())
app.use(router.allowedMethods())

app.listen(8007, () => {
    console.log('服务启动成功');
})

